﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tesseract;


namespace GetClient_info
{
    public class OperationWindowProcess
    {
        public static int ShowIntPtr(IntPtr ptr, int nCmdShow)
        {
            return ShowWindow(ptr, nCmdShow);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="ptr"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="repaint">true表示移动后的窗口是需要重画</param>
        /// <returns></returns>
        public static int MoveWindowFromPtr(IntPtr ptr,int x,int y,int width,int height,bool repaint = true)
        {
            return MoveWindow(ptr, x, y, width, height, repaint);
        }

        #region 系统函数

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int MoveWindow(IntPtr hwnd, int x,int y,int nWidth,int nHeight,bool bRepaint);

        /*
        //hWndInsertAfter 参数可选值:
        HWND_TOP = 0; {在前面}
        HWND_BOTTOM = 1; {在后面}
        HWND_TOPMOST = HWND(-1); {在前面, 位于任何顶部窗口的前面}
        HWND_NOTOPMOST = HWND(-2); {在前面, 位于其他顶部窗口的后面}

        //uFlags 参数可选值:
        SWP_NOSIZE = 1; {忽略 cx、cy, 保持大小}
        SWP_NOMOVE = 2; {忽略 X、Y, 不改变位置}
        SWP_NOZORDER = 4; {忽略 hWndInsertAfter, 保持 Z 顺序}
        SWP_NOREDRAW = 8; {不重绘}
        SWP_NOACTIVATE = $10; {不激活}
        SWP_FRAMECHANGED = $20; {强制发送 WM_NCCALCSIZE 消息, 一般只是在改变大小时才发送此消息}
        SWP_SHOWWINDOW = $40; {显示窗口}
        SWP_HIDEWINDOW = $80; {隐藏窗口}
        */

        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        public static extern int SetWindowPos(IntPtr hwnd, int hWndInsertAfter,int x,int y,int cx,int cy,int wFlags);

        //0.SW_MIOE：隐藏窗口并激活其他窗口。
        //1.SW_MAXIMIZE：最大化指定的窗口。
        //2.SW_MINIMIZE：最小化指定的窗口并且激活在Z序中的下一个顶层窗口。
        //3.SW_RESTORE：激活并显示窗口。如果窗口最小化或最大化，则系统将窗口恢复到原来的尺寸和位置。在恢复最小化窗口时，应用程序应该指定这个标志。
        //4.SW_SHOW：在窗口原来的位置以原来的尺寸激活和显示窗口。
        //5.SW_SHOWDEFAULT：依据在STARTUPINFO结构中指定的SW_FLAG标志设定显示状态，STARTUPINFO 结构是由启动应用程序的程序传递给CreateProcess函数的。
        //6.SW_SHOWMAXIMIZED：激活窗口并将其最大化。
        //7.SW_SHOWMINIMIZED：激活窗口并将其最小化。
        //8.SW_SHOWMINNOACTIVATE：窗口最小化，激活窗口仍然维持激活状态。
        //9.SW_SHOWNA：以窗口原来的状态显示窗口。激活窗口仍然维持激活状态。
        //10.SW_SHOWNOACTIVATE：以窗口最近一次的大小和状态显示窗口。激活窗口仍然维持激活状态。
        //11.SW_SHOWNOMAL：激活并显示一个窗口。如果窗口被最小化或最大化，系统将其恢复到原来的尺寸和大小。应用程序在第一次显示窗口的时候应该指定此标志。
        /// <summary>
        /// 显示窗体,同  ShowWindowAsync 差不多
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="nCmdShow">0-11</param>
        /// <returns></returns>
        [DllImport("user32.dll", EntryPoint = "ShowWindow", CharSet = CharSet.Auto)]
        private static extern int ShowWindow(IntPtr hwnd, int nCmdShow);


        /// <summary> 
        /// 该函数设置由不同线程产生的窗口的显示状态。 (没用)
        /// </summary> 
        /// <param name="hWnd">窗口句柄</param> 
        /// <param name="cmdShow">指定窗口如何显示。查看允许值列表，请查阅ShowWlndow函数的说明部分。</param> 
        /// <returns>如果函数原来可见，返回值为非零；如果函数原来被隐藏，返回值为零。</returns> 
        [DllImport("User32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow);

        /// <summary>
        /// 获取窗体句柄
        /// </summary>，两个参数至少要知道一个
        /// <param name="lpClassName">窗体类名，可以通过Spy++获取，为null表示忽略</param>
        /// <param name="lpWindowName">窗体标题，Text属性，为null时表示忽略</param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        /// <summary>
        /// 根据坐标获取窗口句柄
        /// </summary>
        /// <param name="Point"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern IntPtr WindowFromPoint(Point Point);


        /// <summary>
        /// 获取窗口标题
        /// </summary>
        /// <param name="hWnd">窗口句柄</param>
        /// <param name="lpString">标题</param>
        /// <param name="nMaxCount">最大值</param>
        /// <returns></returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern int GetWindowText(IntPtr hWnd,StringBuilder lpString,int nMaxCount );

        /// <summary>
        ///  获取类的名字
        /// </summary>
        /// <param name="hWnd">句柄</param>
        /// <param name="lpString">类名</param>
        /// <param name="nMaxCount">最大值</param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern int GetClassName(IntPtr hWnd,StringBuilder lpString, int nMaxCount);

        /// <summary>
        /// 该函数将一虚拟键码翻译（映射）成一扫描码或一字符值，或者将一扫描码翻译成一虚拟键码。
        /// </summary>
        /// <param name="uCode">定义一个键的扫描码或虚拟键码。该值如何解释依赖于uMapType参数的值</param>
        /// <param name="uMapType">定义将要执行的翻译。该参数的值依赖于uCode参数的值</param>
        /// <returns></returns>
        //0：代表uCode是一虚拟键码且被翻译为一扫描码。若一虚拟键码不区分左右，则返回左键的扫描码。若未进行翻译，则函数返回O。
        //1：代表uCode是一扫描码且被翻译为一虚拟键码，且此虚拟键码不区分左右。若未进行翻译，则函数返回0。
        //2：代表uCode为一虚拟键码且被翻译为一未被移位的字符值存放于返回值的低序字中。死键（发音符号）则通过设置返回值的最高位来表示。若未进行翻译，则函数返回0。
        //3：代表uCode为一扫描码且被翻译为区分左右键的一虚拟键码。若未进行翻译，则函数返回0。
        [DllImport("user32.dll")]

        private static extern int MapVirtualKey(uint uCode, uint uMapType);


        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

        [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, [Out] StringBuilder lParam);

        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)] // 
        private static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

        [DllImport("User32.dll", EntryPoint = "PostMessage")]
        public static extern int PostMessage(IntPtr hWnd,int Msg,int wParam,int lParam);

        [DllImport("User32.dll ")]
        private static extern IntPtr FindWindowEx(IntPtr parent, IntPtr childe, string strclass, string FrmText);

        /// <summary>
        /// 激活窗体并至最前
        /// </summary>
        /// <param name="hwnd"></param>
        [DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
        public static extern void SetForegroundWindow(IntPtr hwnd);

        [DllImport("user32.dll")]
        private static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);

        [DllImport("user32")]
        private static extern bool GetClientRect(IntPtr hwnd, out RECT lpRect);

        [DllImport("user32.dll")]
        private static extern int GetWindowRect(IntPtr hwnd, out RECT lpRect);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        private static extern IntPtr GetParent(IntPtr hWnd);

        //模拟鼠标点击 移动
        [DllImport("user32")]
        private static extern int mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);

        [DllImport("user32")]
        private static extern int mouse_event(int dwFlags, int dx, int dy, int dwData, IntPtr dwExtraInfo);

        //模拟键盘输入事件
        /// <summary>
        /// 导入模拟键盘的方法
        /// </summary>
        /// <param name="bVk" >按键的虚拟键值</param>
        /// <param name= "bScan" >扫描码，一般不用设置，用0代替就行</param>
        /// <param name= "dwFlags" >选项标志：0：表示按下，2：表示松开</param>
        /// <param name= "dwExtraInfo">一般设置为0</param>
        [DllImport("user32.dll")]
        private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

        [DllImport("user32.dll")]
        private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, IntPtr dwExtraInfo);

        [DllImport("user32.dll")]
        private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);


        [DllImport("gdi32.dll")]
        private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

        [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
        private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);

        //设置鼠标的位置
        [DllImport("user32.dll", EntryPoint = "SetCursorPos")]
        private static extern int SetCursorPos(int x, int y);


        //获取铵键状态
        [DllImport("user32.dll", EntryPoint = "GetKeyboardState")]
        public static extern int GetKeyboardState(byte[] pbKeyState);

        [DllImport("gdi32")]
        public static extern int GetPixel(IntPtr hDC, System.Drawing.Point nXYPos);
        [DllImport("user32")]
        public static extern IntPtr GetDC(IntPtr hWnd);

        /// 尝试调用指定的进程，返回句柄
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr OpenMutex(uint dwDesiredAccess,int bInheritHandle,string lpName);

        /// 创建进程，返回相应的句柄
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr CreateMutex(IntPtr lpMutexAttributes,int bInitialOwner,string lpName);

        #endregion

        /// <summary>
        /// 回调函数代理
        /// </summary>
        private delegate bool CallBack(IntPtr hwnd, int lParam);

        private struct RECT
        {
            public int Left;    //最左坐标
            public int Top;     //最上坐标
            public int Right;   //最右坐标
            public int Bottom;  //最下坐标
        }

        private const int SC_SIZE = 0xF000;
        private const int SC_MOVE = 0xF010;
        private const int SC_MINIMIZE = 0xF020;
        private const int SC_MAXIMIZE = 0xF030;
        private const int SC_NEXTWINDOW = 0xF040;
        private const int SC_PREVWINDOW = 0xF050;
        private const int SC_CLOSE = 0xF060;
        private const int SC_VSCROLL = 0xF070;
        private const int SC_HSCROLL = 0xF080;
        private const int SC_MOUSEMENU = 0xF090;
        private const int SC_KEYMENU = 0xF100;
        private const int SC_ARRANGE = 0xF110;
        private const int SC_RESTORE = 0xF120;
        private const int SC_TASKLIST = 0xF130;
        private const int SC_SCREENSAVE = 0xF140;
        private const int SC_HOTKEY = 0xF150;
        private const int SC_DEFAULT = 0xF160;
        private const int SC_MONITORPOWER = 0xF170;
        private const int SC_CONTEXTHELP = 0xF180;
        private const int SC_SEPARATOR = 0xF00F;
        

        private const int WM_SYSCOMMAND = 0x0112;
        private const int WM_SETTEXT = 0x000C;
        private const int WM_GETTEXT = 0x000D;
        private const int WM_GETTEXTLENGTH = 0x0E;
        private const int WM_LBUTTONDOWN = 0x0201;
        private const int WM_LBUTTONUP = 0x0202;
        private const int WM_CLOSE = 0x0010;
        private const int WM_CLICK = 0x00F5;

        private const int WM_KEYDOWN = 0x100;
        private const int WM_KEYUP = 0x101;

        private const int WM_RETURN = 0X000D;
        private const int VK_HOME = 0x0024;
        private const int VK_RETURN = 0x000D;

        private const int HORZRES = 8;
        private const int VERTRES = 10;
        private const int LOGPIXELSX = 88;
        private const int LOGPIXELSY = 90;
        private const int DESKTOPVERTRES = 117;
        private const int DESKTOPHORZRES = 118;

        //移动鼠标 
        private const int MOUSEEVENTF_MOVE = 0x0001;
        //模拟鼠标左键按下 
        private const int MOUSEEVENTF_LEFTDOWN = 0x0002;
        //模拟鼠标左键抬起 
        private const int MOUSEEVENTF_LEFTUP = 0x0004;
        //模拟鼠标右键按下 
        private const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
        //模拟鼠标右键抬起 
        private const int MOUSEEVENTF_RIGHTUP = 0x0010;
        //模拟鼠标中键按下 
        private const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
        //模拟鼠标中键抬起 
        private const int MOUSEEVENTF_MIDDLEUP = 0x0040;
        //标示是否采用绝对坐标 
        private const int MOUSEEVENTF_ABSOLUTE = 0x8000;
        //模拟鼠标滚轮滚动操作，必须配合dwData参数
        private const int MOUSEEVENTF_WHEEL = 0x0800;

        #region bVk参数 常量定义

        #region MyRegion
        public const byte vbKeyLButton = 0x1;    // 鼠标左键
        public const byte vbKeyRButton = 0x2;    // 鼠标右键
        public const byte vbKeyCancel = 0x3;     // CANCEL 键
        public const byte vbKeyMButton = 0x4;    // 鼠标中键
        public const byte vbKeyBack = 0x8;       // BACKSPACE 键
        public const byte vbKeyTab = 0x9;        // TAB 键
        public const byte vbKeyClear = 0xC;      // CLEAR 键
        public const byte vbKeyReturn = 0xD;     // ENTER 键
        public const byte vbKeyShift = 0x10;     // SHIFT 键
        public const byte vbKeyControl = 0x11;   // CTRL 键
        public const byte vbKeyAlt = 18;         // Alt 键  (键码18)
        public const byte vbKeyMenu = 0x12;      // MENU 键
        public const byte vbKeyPause = 0x13;     // PAUSE 键
        public const byte vbKeyCapital = 0x14;   // CAPS LOCK 键
        public const byte vbKeyEscape = 0x1B;    // ESC 键
        public const byte vbKeySpace = 0x20;     // SPACEBAR 键
        public const byte vbKeyPageUp = 0x21;    // PAGE UP 键
        public const byte vbKeyEnd = 0x23;       // End 键
        public const byte vbKeyHome = 0x24;      // HOME 键
        public const byte vbKeyLeft = 0x25;      // LEFT ARROW 键
        public const byte vbKeyUp = 0x26;        // UP ARROW 键
        public const byte vbKeyRight = 0x27;     // RIGHT ARROW 键
        public const byte vbKeyDown = 0x28;      // DOWN ARROW 键
        public const byte vbKeySelect = 0x29;    // Select 键
        public const byte vbKeyPrint = 0x2A;     // PRINT SCREEN 键
        public const byte vbKeyExecute = 0x2B;   // EXECUTE 键
        public const byte vbKeySnapshot = 0x2C;  // SNAPSHOT 键
        public const byte vbKeyDelete = 0x2E;    // Delete 键
        public const byte vbKeyHelp = 0x2F;      // HELP 键
        public const byte vbKeyNumlock = 0x90;   // NUM LOCK 键 
        #endregion

        #region 常用键 字母键A到Z
        public const byte vbKeyA = 65;
        public const byte vbKeyB = 66;
        public const byte vbKeyC = 67;
        public const byte vbKeyD = 68;
        public const byte vbKeyE = 69;
        public const byte vbKeyF = 70;
        public const byte vbKeyG = 71;
        public const byte vbKeyH = 72;
        public const byte vbKeyI = 73;
        public const byte vbKeyJ = 74;
        public const byte vbKeyK = 75;
        public const byte vbKeyL = 76;
        public const byte vbKeyM = 77;
        public const byte vbKeyN = 78;
        public const byte vbKeyO = 79;
        public const byte vbKeyP = 80;
        public const byte vbKeyQ = 81;
        public const byte vbKeyR = 82;
        public const byte vbKeyS = 83;
        public const byte vbKeyT = 84;
        public const byte vbKeyU = 85;
        public const byte vbKeyV = 86;
        public const byte vbKeyW = 87;
        public const byte vbKeyX = 88;
        public const byte vbKeyY = 89;
        public const byte vbKeyZ = 90;
        #endregion

        #region 数字键盘0到9

        public const byte vbKey0 = 48;    // 0 键
        public const byte vbKey1 = 49;    // 1 键
        public const byte vbKey2 = 50;    // 2 键
        public const byte vbKey3 = 51;    // 3 键
        public const byte vbKey4 = 52;    // 4 键
        public const byte vbKey5 = 53;    // 5 键
        public const byte vbKey6 = 54;    // 6 键
        public const byte vbKey7 = 55;    // 7 键
        public const byte vbKey8 = 56;    // 8 键
        public const byte vbKey9 = 57;    // 9 键


        public const byte vbKeyNumpad0 = 0x60;    //0 键
        public const byte vbKeyNumpad1 = 0x61;    //1 键
        public const byte vbKeyNumpad2 = 0x62;    //2 键
        public const byte vbKeyNumpad3 = 0x63;    //3 键
        public const byte vbKeyNumpad4 = 0x64;    //4 键
        public const byte vbKeyNumpad5 = 0x65;    //5 键
        public const byte vbKeyNumpad6 = 0x66;    //6 键
        public const byte vbKeyNumpad7 = 0x67;    //7 键
        public const byte vbKeyNumpad8 = 0x68;    //8 键
        public const byte vbKeyNumpad9 = 0x69;    //9 键
        public const byte vbKeyMultiply = 0x6A;   // MULTIPLICATIONSIGN(*)键
        public const byte vbKeyAdd = 0x6B;        // PLUS SIGN(+) 键
        public const byte vbKeySeparator = 0x6C;  // ENTER 键
        public const byte vbKeySubtract = 0x6D;   // MINUS SIGN(-) 键
        public const byte vbKeyDecimal = 0x6E;    // DECIMAL POINT(.) 键
        public const byte vbKeyDivide = 0x6F;     // DIVISION SIGN(/) 键 
        #endregion

        #region F1到F12按键

        public const byte vbKeyF1 = 0x70;   //F1 键
        public const byte vbKeyF2 = 0x71;   //F2 键
        public const byte vbKeyF3 = 0x72;   //F3 键
        public const byte vbKeyF4 = 0x73;   //F4 键
        public const byte vbKeyF5 = 0x74;   //F5 键
        public const byte vbKeyF6 = 0x75;   //F6 键
        public const byte vbKeyF7 = 0x76;   //F7 键
        public const byte vbKeyF8 = 0x77;   //F8 键
        public const byte vbKeyF9 = 0x78;   //F9 键
        public const byte vbKeyF10 = 0x79;  //F10 键
        public const byte vbKeyF11 = 0x7A;  //F11 键
        public const byte vbKeyF12 = 0x7B;  //F12 键 
        #endregion

        #endregion



        /// <summary>
        /// 获取窗体句柄
        /// </summary>
        /// <param name="form_name"></param>
        /// <returns></returns>
        public static IntPtr GetIntPtrFromStr(string form_name)
        {
            IntPtr PrtForm = new IntPtr(0);
            Process[] processList = Process.GetProcessesByName(form_name);
            if (processList.Length > 0)
            {
                PrtForm = processList[processList.Length - 1].MainWindowHandle;
                if (PrtForm != IntPtr.Zero)
                    return PrtForm;
            }

            if (PrtForm == IntPtr.Zero)
            {
                PrtForm = FindWindow(null, form_name);
                if (PrtForm != IntPtr.Zero)
                    return PrtForm;
            }
            return PrtForm;
        }

        /// <summary>
        /// 窗体最大化及置顶
        /// </summary>
        /// <param name="mainWnd">窗体句柄</param>
        public static void WindowMaxAndTop(IntPtr mainWnd)
        {
            SetForegroundWindow(mainWnd);//置顶
            SendMessage(mainWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0); //最大化bai
            //ShowWindow(mainWnd, 2);
        }

        public static void WindowMinAndTop(IntPtr mainWnd)
        {
            SetForegroundWindow(mainWnd);//置顶
            SendMessage(mainWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); //最小化bai
            //ShowWindow(mainWnd, 3);
        }

        public static void WindowRestoreAndTop(IntPtr mainWnd)
        {
            SetForegroundWindow(mainWnd);//置顶
            SendMessage(mainWnd, WM_SYSCOMMAND, SC_RESTORE, 0); //回复窗体bai
            //ShowWindow(mainWnd, 4);
        }


        /// <summary>
        /// 置顶
        /// </summary>
        /// <param name="mainWnd"></param>
        public static void WindowTop(IntPtr mainWnd)
        {
            SetForegroundWindow(mainWnd);//置顶
        }


        /// <summary>
        /// 窗体点击事件及置顶
        /// </summary>
        /// <param name="mainWnd">窗体句柄</param>
        /// <param name="ControlWnd">窗体内控件句柄</param>
        public static void button_Click(IntPtr mainWnd, IntPtr ControlWnd)
        {
            //SetForegroundWindow(mainWnd);//置顶
            SendMessage(ControlWnd, WM_CLICK, mainWnd, "0");//鼠标点击一次按钮 
        }

        /// <summary>
        /// 获取指定文本框内容及置顶
        /// </summary>
        /// <param name="mainWnd">窗体句柄</param>
        /// <param name="ControlWnd">窗体内控件句柄</param>
        /// <param name="text">返回的文本内容</param>
        public static void get_Controltext(IntPtr mainWnd, IntPtr ControlWnd, ref string text)
        {
            //SetForegroundWindow(mainWnd);//置顶
            StringBuilder title = new StringBuilder();
            Int32 size = SendMessage(ControlWnd, WM_GETTEXTLENGTH, 0, 0);//获取文本内容长度
            if (size > 0)
            {
                title = new StringBuilder(size + 1);

                SendMessage(ControlWnd, WM_GETTEXT, title.Capacity, title);
                text = title.ToString();
            }
        }

        /// <summary>
        /// 写入指定文本框内容及置顶
        /// </summary>
        /// <param name="mainWnd">窗体句柄</param>
        /// <param name="ControlWnd">窗体内控件句柄</param>
        /// <param name="text">写入的文本内容</param>
        public static void set_Controltext(IntPtr mainWnd, IntPtr ControlWnd, string text)
        {
            SetForegroundWindow(mainWnd);//置顶
            SendMessage(ControlWnd, WM_SETTEXT, mainWnd, text);//填写文本框
        }

        /// <summary>
        /// 发送回车
        /// </summary>
        /// <param name="hwnd"></param>
        public static void Send_enter(IntPtr hand)
        {
            SetForegroundWindow(hand);//激活
            PostMessage(hand, WM_KEYDOWN, VK_RETURN, 0);//回车事件
            PostMessage(hand, WM_KEYUP, VK_RETURN, 0);
        }

        public static void Send_enter2(IntPtr hwnd) 
        {
            SetForegroundWindow(hwnd);//激活
            keybd_event(VK_RETURN, (byte)MapVirtualKey(VK_RETURN, 0), 0, 0);
            keybd_event(VK_RETURN, (byte)MapVirtualKey(VK_RETURN, 0), 2, 0);
        }




        public static void set_Controltext(IntPtr ControlWnd, string text)
        {
            SetForegroundWindow(ControlWnd);//置顶
            StringBuilder ret = new StringBuilder(256);
            SendMessage(ControlWnd, WM_SETTEXT, (IntPtr)100, text);//填写文本框
        }

        public static void get_Controltext(IntPtr ControlWnd, string text)
        {
            StringBuilder title = new StringBuilder();
            Int32 size = SendMessage(ControlWnd, WM_GETTEXTLENGTH, 0, 0);//获取文本内容长度
            if (size > 0)
            {
                title = new StringBuilder(size + 1);

                SendMessage(ControlWnd, WM_GETTEXT, title.Capacity, title);
                text = title.ToString();
            }
        }


        //获取窗体所有窗体控件句柄
        public static int Get_allControl(IntPtr mainWnd, ref List<IntPtr> listWnd, ref List<string> position)
        {
            try
            {
                SetForegroundWindow(mainWnd);//置顶

                //获取外部exe所有控件XY位置与句柄
                List<IntPtr> listbuf = new List<IntPtr>();
                List<string> strbuf = new List<string>();
                EnumChildWindows(mainWnd, new CallBack(delegate (IntPtr hwnd, int lParam)
                {
                    listbuf.Add(hwnd);
                    RECT clientRect;
                    int x = 0, y = 0;
                    IntPtr parerntHandle = GetParent(hwnd); //获得一个指定子窗口的父窗口句柄
                    if (parerntHandle != IntPtr.Zero)
                    {
                        GetWindowRect(hwnd, out clientRect);//返回指定窗口的边框矩形的大小
                        RECT rect;
                        GetWindowRect(parerntHandle, out rect);//返回指定窗口的边框矩形的大小
                        x = clientRect.Left - rect.Left;
                        y = clientRect.Top - rect.Top;
                        strbuf.Add(x + "," + y + " : " + hwnd.ToString());
                    }
                    return true;
                }), 0);


                listWnd = listbuf;
                position = strbuf;
            }
            catch (Exception er)
            {
                return 0;
            }
            return 1;
        }


        //当前系统DPI_X 大小 一般为96
        public static int DpiX
        {
            get
            {
                var hdc = GetDC(IntPtr.Zero);
                var dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
                ReleaseDC(IntPtr.Zero, hdc);
                return dpiX;
            }
        }

        //当前系统DPI_Y 大小 一般为96
        public static int DpiY
        {
            get
            {
                var hdc = GetDC(IntPtr.Zero);
                var dpiX = GetDeviceCaps(hdc, LOGPIXELSY);
                ReleaseDC(IntPtr.Zero, hdc);
                return dpiX;
            }
        }

        /// 获取真实设置的桌面分辨率大小
        public static Size DesktopSize
        {
            get
            {
                var hdc = GetDC(IntPtr.Zero);
                var size = new Size
                {
                    Width = GetDeviceCaps(hdc, DESKTOPHORZRES),
                    Height = GetDeviceCaps(hdc, DESKTOPVERTRES)
                };
                ReleaseDC(IntPtr.Zero, hdc);
                return size;
            }
        }

        /// 获取屏幕分辨率当前物理大小
        /// 
        public static Size WorkingArea
        {
            get
            {
                var hdc = GetDC(IntPtr.Zero);
                var size = new Size
                {
                    Width = GetDeviceCaps(hdc, HORZRES),
                    Height = GetDeviceCaps(hdc, VERTRES)
                };
                ReleaseDC(IntPtr.Zero, hdc);
                return size;
            }
        }

        /// <summary>
        /// 获得横轴缩放比
        /// 此参数为[控制面板-设置-显示-更改文本、应用等项目的大小]所显示的百分比
        /// </summary>
        public static float ScaleX => DpiX / 96f;

        /// <summary>
        /// 获得纵轴缩放比
        /// 此参数为[控制面板-设置-显示-更改文本、应用等项目的大小]所显示的百分比
        /// </summary>
        public static float ScaleY => DpiY / 96f;


        #region //模拟鼠标键盘

        /// <summary>
        /// 鼠标移动到指定的绝对位置
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns>return 1 代表成功</returns>
        public static int SetMouseLocation (int x, int y)
        {
            return SetCursorPos(x, y);
        }

        /// <summary>
        /// 键盘输入字符
        /// </summary>
        /// <param name="str"></param>
        /// <param name="prt"></param>
        public static void Keybd_event(string str, IntPtr prt)
        {
            if (str == "") return;
            char[] user = str.ToCharArray();
            foreach (var buf in user)
            {
                keybd_event((byte)buf, 0x45, 0, prt);//键按下
                keybd_event((byte)buf, 0x45, 2, prt);//键释放
            }
        }

        /// <summary>
        /// 键盘输入字节
        /// </summary>
        /// <param name="str"></param>
        /// <param name="prt"></param>
        /// <param name="sta"></param>
        public static void Keybd_event(byte str, IntPtr prt, bool sta = false)
        {
            if (sta)
                keybd_event((byte)str, 0, 0, prt);//键按下
            else
                keybd_event((byte)str, 0, 2, prt);//键释放
        }

        /// <summary>
        /// 鼠标移动到指定的绝对位置按下
        /// </summary>
        /// <param name="x">移动位置x</param>
        /// <param name="y">移动位置y</param>
        /// <param name="dx">显示实际分辨率x</param>
        /// <param name="dy">显示实际分辨率y</param>
        public static void Mouse_down(int x, int y, int dx, int dy, IntPtr prt)
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x * 65536 / dx, y * 65536 / dy, 0, prt);//相对当前鼠标位置x轴和y轴分别移动50像素
        }

        /// <summary>
        /// 鼠标移动到指定的绝对位置弹起
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="dx">屏幕当前分辨率宽</param>
        /// <param name="dy">屏幕当前分辨率高</param>
        /// <param name="prt">0</param>
        public static void Mouse_up(int x, int y, int dx, int dy, IntPtr prt)
        {
            mouse_event(MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x * 65536 / dx, y * 65536 / dy, 0, prt);//相对当前鼠标位置x轴和y轴分别移动50像素
        }

        /// <summary>
        /// 鼠标移动到指定的绝对位置单击一次 ,如需双击重复再调用一次
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <param name="prt"></param>
        public static void Mouse_click(int x, int y, int dx, int dy)
        {
            mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x * 65536 / dx, y * 65536 / dy, 0, 0);//相对当前鼠标位置x轴和y轴分别移动50像素
        }

        // 
        public static void Mouse_wheel(int x, int y, int dx, int dy, IntPtr prt)
        {
            mouse_event( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_WHEEL , x * 65536 / dx, y * 65536 / dy, 0, prt);//相对当前鼠标位置x轴和y轴分别移动50像素
        }



        /// <summary>
        /// 鼠标移动到指定的绝对位置
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="dx">屏幕当前分辨率宽</param>
        /// <param name="dy">屏幕当前分辨率高</param>
        /// <param name="prt">输入0</param>
        public static void Mouse_move(int x, int y, int dx, int dy, IntPtr prt)
        {
            mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x * 65536 / dx, y * 65536 / dy, 0, prt);//相对当前鼠标位置x轴和y轴分别移动50像素
        }

        /// <summary>
        /// 鼠标移动到指定的绝对位置
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public static void Mouse_SetMousePos(int x, int y)
        {
            SetCursorPos(x, y);
        }

        /// <summary>
        /// 通过句柄获取坐标与控件大小
        /// </summary>
        /// <param name="ptr"></param>
        public static void GetWindowRect(IntPtr ptr,ref int x,ref int y,ref int width,ref int height)
        { 
            RECT rect;
            if (GetWindowRect(ptr, out rect) == 1)
            {
                x = rect.Left;
                y = rect.Top;
                width = rect.Right - rect.Left;
                height = rect.Bottom - rect.Top;
            }
            else
            {
                x = 0;
                y = 0;
                width = 0;
                height = 0;
            }
        }

        //获取大小写状态
        public static bool get_CapsLockStatus
        {
            get
            {
                byte[] bs = new byte[256];
                GetKeyboardState(bs);
                return (bs[0x14] == 1);
            }
        }

        //获取小键盘状态
        public static bool get_NumLockStatus
        {
            get
            {
                byte[] bs = new byte[256];
                GetKeyboardState(bs);
                return (bs[0x90] == 1);
            }
        }

        const int KEYEVENTF_EXTENDEDKEY = 0x1;
        const int KEYEVENTF_KEYUP = 0x2;
        const int VK_NUMLOCK = 0x90;
        const int VK_CAPITAL = 0x14;

        //设置大小写铵键
        public void set_CapitalState()
        {
            keybd_event(VK_CAPITAL, 0x45, KEYEVENTF_EXTENDEDKEY, (UIntPtr)0);
            keybd_event(VK_CAPITAL, 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, (UIntPtr)0);
            Application.DoEvents();
        } 



        #endregion


        /// <summary>
        /// 截取桌面返回图片
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static int CaptureDesktop(int sourceX, int sourceY, int width, int height, out Bitmap out_bmp)
        {
            try
            {
                out_bmp = new Bitmap(width, height);
                using (Graphics g = Graphics.FromImage(out_bmp))
                {
                    Size size = new Size(width, height);
                    g.CopyFromScreen(sourceX, sourceY, 0, 0, size);
                }
                out_bmp = out_bmp.Clone(new Rectangle(0, 0, width, height), System.Drawing.Imaging.PixelFormat.Undefined);
                return 0;
            }
            catch (Exception e)
            {
                out_bmp = null;
                return 1;
            }
        }

        /// <summary>
        /// 截取桌面返回图片
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static int CaptureDesktop(int width, int height, out Bitmap out_bmp)
        {
            try
            {
                out_bmp = new Bitmap(width, height);
                using (Graphics g = Graphics.FromImage(out_bmp))
                {
                    Size size = new Size(width, height);
                    g.CopyFromScreen(new Point(0, 0), new Point(0, 0), size);
                }
                out_bmp = out_bmp.Clone(new Rectangle(0, 0, width, height), PixelFormat.Undefined);
                return 0;
            }
            catch (Exception e)
            {
                out_bmp = null;
                return 1;
            }
        }

        /// <summary>
        /// 截图图片
        /// </summary>
        /// <param name="img"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="out_img"></param>
        /// <returns></returns>
        public static int CaptureImg(Bitmap img, int x, int y, int width, int height, out Bitmap out_img)
        {
            try
            {
                Bitmap bmp = new Bitmap(width, height);
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    //g.DrawImage(img, x, y, width, height);
                    g.DrawImage(img, new Rectangle(0, 0, width, height), x, y, width, height, GraphicsUnit.Pixel);
                    //g.DrawImageUnscaledAndClipped(img, new Rectangle(x, y, width, height));
                    //g.DrawImageUnscaled(img, x, y, width, height);
                }
                out_img = bmp;
                return 0;
            }
            catch
            {
                out_img = null;
                return 1;
            }
        }

        /// <summary>
        /// 字符解析
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="switch_"></param>
        /// <returns></returns>
        public static string ocr_(string FileName, bool switch_ = false)
        {
            try
            {
                //Bitmap image = null;
                Bitmap image = (Bitmap)Bitmap.FromFile(FileName, false);
                image = PreprocesImage(image);

                //pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
                //pictureBox1.Image = (Image)image.Clone();
                //ocr分析
                if (image != null)
                {
                    if (switch_)//多字符
                    {
                        using (var engine = new TesseractEngine("tessdata", "eng+chi_sim", EngineMode.Default))
                        {
                            using (var page = engine.Process(image))
                            {
                                return page.GetText();
                            }

                        }
                    }
                    else//单个字符
                    {
                        using (var engine = new TesseractEngine("tessdata", "eng+chi_sim", EngineMode.Default))
                        {
                            engine.DefaultPageSegMode = PageSegMode.SingleChar;
                            engine.SetVariable("tessedit_char_whitelist", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"); // If digit only
                            using (var page = engine.Process(image))
                            {
                                return page.GetText();
                            }

                        }

                    }

                }
                else return "";
            }
            catch (Exception er)
            {
                return er.ToString();
            }
        }

        public static string ocr_B(Bitmap image, bool switch_ = false)
        {
            try
            {
                Bitmap image_buf = image;
                image_buf = PreprocesImage2(image_buf);

                //pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
                //pictureBox1.Image = (Image)image.Clone();
                //ocr分析
                if (image != null)
                {
                    if (switch_)//多字符
                    {
                        //eng+
                        using (var engine = new TesseractEngine("tessdata", "eng+chi_sim", EngineMode.Default))
                        {
                            using (var page = engine.Process(image_buf))
                            {
                                return page.GetText().Trim();
                            }

                        }
                    }
                    else//单个字符
                    {
                        using (var engine = new TesseractEngine("tessdata", "eng+chi_sim", EngineMode.Default))
                        {
                            engine.DefaultPageSegMode = PageSegMode.SingleChar;
                            engine.SetVariable("tessedit_char_whitelist", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"); // If digit only
                            using (var page = engine.Process(image_buf))
                            {
                                return page.GetText().Trim();
                            }

                        }

                    }
                }
                else return "";
            }
            catch (Exception er)
            {
                return er.ToString();
            }
        }
        public static string ocr_(Bitmap image, bool switch_ = false)
        {
            try
            {
                Bitmap image_buf = image;
                image_buf = PreprocesImage(image_buf);

                //pictureBox1.SizeMode = PictureBoxSizeMode.Zoom;
                //pictureBox1.Image = (Image)image.Clone();
                //ocr分析
                if (image != null)
                {
                    if (switch_)//多字符
                    {
                        using (var engine = new TesseractEngine("tessdata", "eng+chi_sim", EngineMode.Default))
                        {
                            using (var page = engine.Process(image_buf))
                            {
                                return page.GetText();
                            }

                        }
                    }
                    else//单个字符
                    {
                        using (var engine = new TesseractEngine("tessdata", "eng+chi_sim", EngineMode.Default))
                        {
                            engine.DefaultPageSegMode = PageSegMode.SingleChar;
                            engine.SetVariable("tessedit_char_whitelist", "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-"); // If digit only
                            using (var page = engine.Process(image_buf))
                            {
                                return page.GetText();
                            }

                        }

                    }

                }
                else return "";
            }
            catch (Exception er)
            {
                return er.ToString();
            }
        }
        /// <summary>
        /// 图片颜色区分，剩下白色和黑色
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static Bitmap PreprocesImage(Bitmap image)
        {
            //You can change your new color here. Red,Green,LawnGreen any..
            Color actualColor;
            //make an empty bitmap the same size as scrBitmap
            image = ResizeImage(image, image.Width * 2, image.Height * 2);
            //image.Save(@"D:\UpWork\OCR_WinForm\Preprocess_Resize.jpg");

            Bitmap newBitmap = new Bitmap(image.Width, image.Height);
            for (int i = 0; i < image.Width; i++)
            {
                for (int j = 0; j < image.Height; j++)
                {
                    //get the pixel from the scrBitmap image
                    actualColor = image.GetPixel(i, j);
                    // > 150 because.. Images edges can be of low pixel colr. if we set all pixel color to new then there will be no smoothness left.
                    if (actualColor.R > 100 || actualColor.G > 100 || actualColor.B > 100)//在这里设置RGB
                        newBitmap.SetPixel(i, j, Color.White);
                    else
                        newBitmap.SetPixel(i, j, Color.Black);
                }
            }
            return newBitmap;
        }


        //白色转换成黑色
        public static Bitmap PreprocesImage2(Bitmap image)
        {
            //You can change your new color here. Red,Green,LawnGreen any..
            Color actualColor;
            //make an empty bitmap the same size as scrBitmap
            image = ResizeImage(image, image.Width * 2, image.Height * 2);
            //image.Save(@"D:\UpWork\OCR_WinForm\Preprocess_Resize.jpg");

            Bitmap newBitmap = new Bitmap(image.Width, image.Height);
            for (int i = 0; i < image.Width; i++)
            {
                for (int j = 0; j < image.Height; j++)
                {
                    //get the pixel from the scrBitmap image
                    actualColor = image.GetPixel(i, j);
                    // > 150 because.. Images edges can be of low pixel colr. if we set all pixel color to new then there will be no smoothness left.
                    if (actualColor.R < 200 || actualColor.G < 200 || actualColor.B < 200)//在这里设置RGB
                        newBitmap.SetPixel(i, j, Color.White);
                    else
                        newBitmap.SetPixel(i, j, Color.Black);
                }
            }
            return newBitmap;
        }

        /// <summary>
        /// 调整图片大小和对比度
        /// </summary>
        /// <param name="image"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static Bitmap ResizeImage(Image image, int width, int height)
        {
            var destRect = new Rectangle(0, 0, width, height);
            var destImage = new Bitmap(width, height);

            destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution * 2);//2,3
                                                                                              //image.Save(@"D:\UpWork\OCR_WinForm\Preprocess_HighRes.jpg");

            using (var graphics = Graphics.FromImage(destImage))
            {
                graphics.CompositingMode = CompositingMode.SourceOver;
                graphics.CompositingQuality = CompositingQuality.HighQuality;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = SmoothingMode.HighQuality;
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

                using (var wrapMode = new ImageAttributes())
                {
                    wrapMode.SetWrapMode(WrapMode.Clamp);
                    graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
                }
            }

            return destImage;
        }

        //获取图片区域指定颜色范围，并返回布尔
        public static bool get_rgbstate(Bitmap img,int Rv,int Gv,int Bv, int Max_v, int Min_v)
        {
            bool state = false;
            try
            {
                //锁定位图
                Rectangle rect = new Rectangle(0, 0, img.Width, img.Height);
                BitmapData bmpData = img.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                int stride = bmpData.Stride;
                int rgb_count = 0;
                unsafe
                {
                    byte* pIn = (byte*)bmpData.Scan0.ToPointer();
                    byte* P;
                    int R, G, B;
                    for (int y = 0; y < bmpData.Height; y++)
                    {
                        for (int x = 0; x < bmpData.Width; x++)
                        {
                            P = pIn;
                            B = P[0];
                            G = P[1];
                            R = P[2];
                            pIn += 3;

                            //Debug.WriteLine(B.ToString()+","+ G.ToString() + "," + R.ToString());

                            if ((Rv+ Max_v) >= R && (Rv - Min_v) <= R &&
                                (Gv + Max_v) >= G && (Gv - Min_v) <= G &&
                                (Bv + Max_v) >= B && (Bv - Min_v) <= B
                                )
                            {
                                rgb_count++;
                            }
                            else
                            {
                                ;
                            }
                        }
                        pIn += stride - bmpData.Width * 3;
                    }

                    int _intcount = (int)(bmpData.Height * bmpData.Width * 0.8f);
                    if (rgb_count > _intcount)
                    {
                        state = true;
                    }
                }

                //解锁位图
                img.UnlockBits(bmpData);
            }
            catch (Exception er)
            {
                state = false;
            }
            return state;
        }

        /// <summary>
        /// 设置程序开机启动
        /// </summary>
        /// <param name="strAppPath">应用程序exe所在文件夹</param>
        /// <param name="strAppName">应用程序exe名称</param>
        /// <param name="bIsAutoRun">自动运行状态</param>
        public static void SetAutoRun(string strAppPath, string strAppName, bool bIsAutoRun)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(strAppPath)|| string.IsNullOrWhiteSpace(strAppName))
                {
                    throw new Exception("应用程序路径或名称为空！");
                }
                RegistryKey reg = Registry.CurrentUser;
                //RegistryKey reg = Registry.LocalMachine;
                //RegistryKey run = reg.CreateSubKey(@"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\");
                RegistryKey run = reg.CreateSubKey(@"Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Run");
                if (bIsAutoRun)
                {
                    run.SetValue(strAppName, strAppPath);
                }
                else
                {
                    if (null != run.GetValue(strAppName))
                    {
                        run.DeleteValue(strAppName,false);
                    }
                }
                run.Close();
                reg.Close();
            }
            catch (Exception ex)
            {
                //throw new Exception(ex.Message, ex);
            }
        }
        /// <summary>
        /// 判断是否开机启动
        /// </summary>
        /// <param name="strAppPath">应用程序路径</param>
        /// <param name="strAppName">应用程序名称</param>
        /// <returns></returns>
        public static bool IsAutoRun(string strAppPath, string strAppName)
        {
            try
            {
                RegistryKey reg = Registry.CurrentUser;
                //RegistryKey reg = Registry.LocalMachine;
                RegistryKey software = reg.OpenSubKey(@"SOFTWARE");
                RegistryKey run = reg.OpenSubKey(@"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\");
                object key = run.GetValue(strAppName);
                software.Close();
                run.Close();
                if (null == key || !strAppPath.Equals(key.ToString()))
                {
                    return false;
                }
                return true;
            }
            catch (Exception ex)
            {
                //throw new Exception(ex.Message, ex);
                return false;
            }
        }


        /// <summary>
        /// 为指定用户组，授权目录指定完全访问权限
        /// </summary>
        /// <param name="user">用户组，如Users</param>
        /// <param name="folder">实际的目录</param>
        /// <returns></returns>
        public static bool SetAccess(string user, string folder)
        {
            //定义为完全控制的权限
            const FileSystemRights Rights = FileSystemRights.FullControl;

            //添加访问规则到实际目录
            var AccessRule = new FileSystemAccessRule(user, Rights,
                InheritanceFlags.None,
                PropagationFlags.NoPropagateInherit,
                AccessControlType.Allow);

            var Info = new DirectoryInfo(folder);
            var Security = Info.GetAccessControl(AccessControlSections.Access);

            bool Result;
            Security.ModifyAccessRule(AccessControlModification.Set, AccessRule, out Result);
            if (!Result) return false;

            //总是允许再目录上进行对象继承
            const InheritanceFlags iFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;

            //为继承关系添加访问规则
            AccessRule = new FileSystemAccessRule(user, Rights,
                iFlags,
                PropagationFlags.InheritOnly,
                AccessControlType.Allow);

            Security.ModifyAccessRule(AccessControlModification.Add, AccessRule, out Result);
            if (!Result) return false;

            Info.SetAccessControl(Security);

            return true;
        }

        /// <summary>
        /// 关闭或开启UAC提示 
        /// </summary>
        /// <returns></returns>
        public static bool DisableUAC()
        {
            try
            {
                string path = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System";
                string uac = "EnableLUA";
                RegistryKey key = Registry.LocalMachine.CreateSubKey(path);
                //RegistryKey key = Registry.CurrentUser.CreateSubKey(path);
                if (key != null)
                {
                    key.SetValue(uac, 0, RegistryValueKind.DWord);
                    key.Close();
                }

                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 可以同时调用这个函数，在关闭UAC后，系统不会在通知里显示提示
        /// </summary>
        private void SetNoWindowsNotify()
        {
            string path = @"SOFTWARE\Microsoft\Security Center";
            string notify = "UACDisableNotify";
            RegistryKey key = Registry.LocalMachine.CreateSubKey(path);
            if (key != null)
            {
                key.SetValue(notify, 1, RegistryValueKind.DWord);
                key.Close();
            }
        }



        /// <summary>
        /// 电脑重启函数
        /// </summary>
        public static void Reboot()
        {
            Process.Start("shutdown", " -r -t 0");
        }

        /// <summary>
        /// 获取当前是否是管理员或非管理员
        /// </summary>
        /// <returns></returns>
        public static bool IsAdministrator()
        {
            WindowsIdentity identity = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(identity);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }


        /// <summary>
        /// 运行外面EXE 
        /// </summary>
        /// <param name="exePath">全路径</param>
        public static bool Run_exe(string exePath)
        {
            bool isExist = false;
            try
            {
                Process m_Process = null;
                m_Process = new Process();
                m_Process.StartInfo.FileName = exePath;
                m_Process.Start();

                //判断程序是否在运行
                while (!isExist)
                {
                    m_Process.WaitForExit(1000);
                    if (m_Process.HasExited == false)
                    {
                        //Console.WriteLine("still running");
                        isExist = true;
                        break;
                    }
                    else
                    {
                        //Console.WriteLine("is finished");
                        isExist = false;
                        break;
                    }
                }
            }
            catch
            {
               return isExist;
            }
            return isExist;

        }

        /// <summary>
        /// 用来判断一个指定的程序是否正在运行
        /// </summary>
        /// <param name="appId">程序名称,长一点比较好,防止有重复</param>
        /// <returns>如果程序是第一次运行返回True,否则返回False</returns>
        public static bool IsFirst(string appId)
        {
            bool state = false;
            try
            {
                Process[] arrayProcess = Process.GetProcessesByName(appId);

                foreach (Process p in arrayProcess)
                {
                    if (p.Id !=0 )
                    {
                        state = true;
                        break;
                    }
                }
            }
            catch (Exception)
            {

                return false;
            }
            return state;
        }



    }
}
